//
//  StatusListViewModel.swift
//  SinaWeibo
//
//  Created by 小果 on 16/2/12.
//  Copyright © 2016年 小果. All rights reserved.
//

import UIKit
import ReactiveCocoa
import SDWebImage

// 微博列表的视图模型 - 分离网络方法
class StatusListViewModel: NSObject {

    /// 微博数据数组
    /// since_id 是第一项
    var statuses = [StatusViewModel]()
    
    /// 加载微博数据(isPulUpRefresh: 是否是上拉刷新标记)
    func loadStatuses(isPullUpRefresh isPullUpRefresh: Bool) ->RACSignal {
        // 初始刷新：status 数组中没有内容
        // 下拉刷新：取 status 中的第一项的 id 作为since_id
        var since_id = statuses.first?.status.id ?? 0
        
        // 上拉刷新：取 status 中的最后一项的 id 作为 max_id
        /// max_id 是最后一项
        var max_id = 0
        if isPullUpRefresh {
            since_id = 0
            max_id = statuses.last?.status.id ?? 0
        }

        return RACSignal.createSignal({ [weak self] (subscriber) -> RACDisposable! in
            
            NetworkTools.sharedTools.loadStatus(since_id: since_id, max_id: max_id).subscribeNext({ (result) -> Void in
                //            printLog(result)
                // 获取result中的statuses的字典数组
                guard let array = result["statuses"] as? [[String:AnyObject]] else {
                    printLog("没有正确的数组")
                    
                    subscriber.sendError(NSError(domain:"xgsinaweibo", code: -1005, userInfo: ["error message": "没有正确的数据"]))
                    return
                }
                //            printLog(array)
                
                // 创建一个临时的数组,记录当前网络请求返回的结果
                var arrayM = [StatusViewModel]()
                // 遍历数组,字典转模型
                for dict in array {
                    arrayM.append(StatusViewModel(status: Status(dict: dict)))
                }
                
                printLog("刷新到 \(arrayM.count) 条微博")
                // 添加一个尾随闭包
                self?.cacheWebImage(arrayM) {
                    if max_id > 0 {  // 此处的功能是将刷新出来的新的数据拼接到现有数组的后面
                       self?.statuses += arrayM
                        
                    }else {  // 此处的功能是刚开始进入界面的时候的刷新和下拉之后的刷新
                       self?.statuses = arrayM + self!.statuses
                    }
                    // 如果是下拉刷新就提示用户
                    if since_id > 0 {
                        // 切记：RAC 是OC的，通知用户,数据是下拉刷新提供的
                        subscriber.sendNext(arrayM.count)
                    }
                    
                    // 通知调用方数据加载完成
                    subscriber.sendCompleted()
                }
                
    
                }, error: { (error) -> Void in
                subscriber.sendError(error)
                    
                }) { () -> Void in
//                    printLog("完成")
            }
            return nil
        })
        
    }
    
    private func cacheWebImage(array: [StatusViewModel], finished: () -> ()) {
        ///  1、定义一个调度组
        let group = dispatch_group_create()
        ///  记录图像的大小
        var dataImageLength = 0
        
        ///  遍历视图模型数组
        for viewModel in array {
            // 只缓存单张图片
            let count = viewModel.thumbnailURLs?.count ?? 0
            
            if count != 1 {
                continue
            }
            ///  2、加入组（切记：enter和leave要配对出现，enter后要紧跟block,leave要放在block的最后一个）
            dispatch_group_enter(group)
            
            ///  使用SDWebImage的核心函数下载图片
            SDWebImageManager.sharedManager().downloadImageWithURL(viewModel.thumbnailURLs![0], options: [], progress: nil, completed: { (image, _, _, _, _) in
                // 当代码执行到这个地方的时候，图片的缓存已经完成,此处不一定有Image
                if image != nil {
                    // 将Image图像转换成二进制数据
                    let data = UIImagePNGRepresentation(image)
                    dataImageLength += data?.length ?? 0
                }
                
                // 3、出组(block的最后一句)
                dispatch_group_leave(group)
            })
            
        }
        ///  调度组的监听
        dispatch_group_notify(group, dispatch_get_main_queue()) {
            printLog("缓存图像已完成\(dataImageLength / 1024)K")
            
            // 执行闭包
            finished()
        }
        
    }

}
    

